#!/usr/bin/env python3
"""
Linux平台打包模块
提供Linux平台专用的应用程序打包功能
"""

import os
import subprocess
import shutil
from pathlib import Path
import tomli

# 项目根目录
PROJECT_ROOT = Path(__file__).parent.parent
RESOURCES_DIR = PROJECT_ROOT / "resources"
BUILD_DIR = PROJECT_ROOT / "build"
DIST_DIR = PROJECT_ROOT / "dist"

def build_linux_package(name, main_script, config):
    """
    Linux平台打包
    
    参数:
        name (str): 应用程序名称
        main_script (str): 主脚本文件名
        config (object): 打包配置对象，包含以下属性：
            - one_file (bool): 是否使用单文件模式
            - windowed (bool): 是否使用窗口模式
            - build_type (str): 打包类型 ('app' 或 'installer')
    
    返回:
        bool: 打包是否成功
    """
    print("正在打包Linux应用程序...")
    
    cmd = [
        "pyinstaller",
        "--name", name,
        "--distpath", str(DIST_DIR),
        "--workpath", str(BUILD_DIR),
        "--specpath", str(BUILD_DIR),
    ]
    
    if config.one_file:
        cmd.append("--onefile")
    
    if config.windowed:
        cmd.append("--windowed")
    
    # 添加图标
    icon_path = RESOURCES_DIR / "icons" / "app-icon.png"
    if icon_path.exists():
        cmd.extend(["--icon", str(icon_path)])
    
    # 添加数据文件
    cmd.extend(["--add-data", f"{RESOURCES_DIR}{os.pathsep}resources"])
    
    # PySide6相关配置
    cmd.extend([
        "--hidden-import", "PySide6.QtCore",
        "--hidden-import", "PySide6.QtGui", 
        "--hidden-import", "PySide6.QtWidgets",
        "--collect-all", "PySide6",
        "--collect-all", "shiboken6"
    ])
    
    cmd.append(str(PROJECT_ROOT / main_script))
    
    try:
        subprocess.run(cmd, check=True)
        print("Linux应用程序打包完成!")
        
        if config.build_type == "installer":
            return _create_linux_installer(name)
        
        print(f"输出目录: {DIST_DIR}")
        return True
        
    except subprocess.CalledProcessError as e:
        print(f"打包失败: {e}")
        return False

def _create_linux_installer(name):
    """创建Linux安装程序（DEB/RPM格式）"""
    print("创建Linux DEB/RPM安装包...")
    
    # 检查必要工具
    has_fpm = shutil.which("fpm") is not None
    has_dpkg = shutil.which("dpkg") is not None
    has_rpm = shutil.which("rpm") is not None
    
    if not any([has_fpm, has_dpkg, has_rpm]):
        print("警告: 未找到任何打包工具(fpm/dpkg/rpm)，跳过安装包创建")
        return True
    
    try:
        # 准备打包目录
        package_dir = BUILD_DIR / "linux_package"
        if package_dir.exists():
            shutil.rmtree(package_dir)
        package_dir.mkdir(parents=True, exist_ok=True)
        
        # 创建目录结构
        usr_bin = package_dir / "usr" / "bin"
        usr_share = package_dir / "usr" / "share"
        applications_dir = package_dir / "usr" / "share" / "applications"
        icons_dir = package_dir / "usr" / "share" / "pixmaps"
        
        usr_bin.mkdir(parents=True, exist_ok=True)
        applications_dir.mkdir(parents=True, exist_ok=True)
        icons_dir.mkdir(parents=True, exist_ok=True)
        
        # 复制可执行文件
        exe_path = DIST_DIR / name
        if exe_path.exists():
            shutil.copy2(exe_path, usr_bin / name)
            (usr_bin / name).chmod(0o755)
        else:
            print("无法找到可执行文件")
            return False
        
        # 创建.desktop文件
        desktop_content = f"""[Desktop Entry]
Version=1.0
Type=Application
Name={name}
Exec=/usr/bin/{name}
Icon=/usr/share/pixmaps/{name}.png
Terminal=false
Categories=Utility;
"""
        
        desktop_file = applications_dir / f"{name}.desktop"
        with open(desktop_file, 'w') as f:
            f.write(desktop_content)
        desktop_file.chmod(0o644)
        
        # 复制图标
        icon_path = RESOURCES_DIR / "icons" / "app-icon.png"
        if icon_path.exists():
            shutil.copy2(icon_path, icons_dir / f"{name}.png")
        
        # 创建DEB包
        deb_success = False
        if has_fpm or has_dpkg:
            deb_success = _create_deb_package(name, package_dir)
        
        # 创建RPM包
        rpm_success = False
        if has_fpm or has_rpm:
            rpm_success = _create_rpm_package(name, package_dir)
        
        # 清理打包目录
        if package_dir.exists():
            shutil.rmtree(package_dir)
        
        return deb_success or rpm_success
        
    except Exception as e:
        print(f"创建Linux安装包失败: {e}")
        return False

def _create_deb_package(name, package_dir):
    """创建DEB安装包"""
    print("创建DEB安装包...")
    
    # 从pyproject.toml读取版本信息
    pyproject_path = PROJECT_ROOT / "pyproject.toml"
    version = "1.0.0"
    try:
        with open(pyproject_path, "rb") as f:
            pyproject_data = tomli.load(f)
            version = pyproject_data.get("project", {}).get("version", "1.0.0")
    except FileNotFoundError:
        pass
    
    try:
        cmd = [
            "fpm" if shutil.which("fpm") else "dpkg-deb",
            "--input-type", "dir" if shutil.which("fpm") else "--build",
            "--output-type", "deb" if shutil.which("fpm") else "",
            "--name", name,
            "--version", version,
            "--architecture", "amd64",
            "--description", f"{name} - A Python application",
            "--maintainer", "Maintainer <maintainer@example.com>",
            "--package", str(DIST_DIR / f"{name}_{version}_amd64.deb"),
            str(package_dir)
        ]
        
        # 根据使用的工具调整参数
        if shutil.which("fpm"):
            cmd = [
                "fpm", "-s", "dir", "-t", "deb",
                "-n", name, "-v", version, "--architecture", "amd64",
                "-C", str(package_dir), "."
            ]
            result = subprocess.run(cmd, cwd=package_dir.parent, check=True)
            # 移动生成的deb文件到dist目录
            deb_files = list(package_dir.parent.glob("*.deb"))
            for deb_file in deb_files:
                shutil.move(str(deb_file), str(DIST_DIR / deb_file.name))
        else:
            # 使用dpkg-deb
            deb_path = DIST_DIR / f"{name}_{version}_amd64.deb"
            cmd = ["dpkg-deb", "--build", str(package_dir), str(deb_path)]
            result = subprocess.run(cmd, check=True)
        
        deb_file = DIST_DIR / f"{name}_{version}_amd64.deb"
        if deb_file.exists():
            print(f"DEB安装包创建完成: {deb_file}")
            return True
        else:
            print("DEB创建失败")
            return False
            
    except subprocess.CalledProcessError as e:
        print(f"创建DEB包失败: {e}")
        return False

def _create_rpm_package(name, package_dir):
    """创建RPM安装包"""
    print("创建RPM安装包...")
    
    # 从pyproject.toml读取版本信息
    pyproject_path = PROJECT_ROOT / "pyproject.toml"
    version = "1.0.0"
    try:
        with open(pyproject_path, "rb") as f:
            pyproject_data = tomli.load(f)
            version = pyproject_data.get("project", {}).get("version", "1.0.0")
    except FileNotFoundError:
        pass
    
    try:
        if shutil.which("fpm"):
            cmd = [
                "fpm", "-s", "dir", "-t", "rpm",
                "-n", name, "-v", version, "--architecture", "x86_64",
                "-C", str(package_dir), "."
            ]
            result = subprocess.run(cmd, cwd=package_dir.parent, check=True)
            
            # 移动生成的rpm文件到dist目录
            rpm_files = list(package_dir.parent.glob("*.rpm"))
            for rpm_file in rpm_files:
                shutil.move(str(rpm_file), str(DIST_DIR / rpm_file.name))
        
        elif shutil.which("rpmbuild"):
            # 使用rpmbuild
            rpm_spec = f"""
Name: {name}
Version: {version}
Release: 1
Summary: {name} Python application
License: MIT
URL: https://example.com
Source0: {name}-{version}.tar.gz
BuildArch: x86_64

%description
{name} is a Python application

%install
mkdir -p %{{buildroot}}
cp -a {package_dir}/* %{{buildroot}}/

%files
/usr/bin/{name}
/usr/share/applications/{name}.desktop
/usr/share/pixmaps/{name}.png
"""
            
            # 创建.spec文件
            spec_file = BUILD_DIR / f"{name}.spec"
            with open(spec_file, 'w') as f:
                f.write(rpm_spec)
            
            cmd = ["rpmbuild", "-bb", "--define", f"_topdir {BUILD_DIR}", str(spec_file)]
            result = subprocess.run(cmd, check=True)
            
            # 查找生成的RPM文件
            rpm_files = list(BUILD_DIR.glob("RPMS/**/*.rpm"))
            if rpm_files:
                rpm_file = rpm_files[0]
                shutil.move(str(rpm_file), str(DIST_DIR / f"{name}-{version}-1.x86_64.rpm"))
        else:
            print("未找到RPM打包工具")
            return False
        
        rpm_file = DIST_DIR / f"{name}-{version}-1.x86_64.rpm"
        if rpm_file.exists():
            print(f"RPM安装包创建完成: {rpm_file}")
            return True
        else:
            print("RPM创建失败")
            return False
            
    except subprocess.CalledProcessError as e:
        print(f"创建RPM包失败: {e}")
        return False